﻿using System;
using System.Collections.Generic;
using Eflong.MonitoringLib.MonitoringUnit;
using Modalities = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities;
using States = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitState.States;

namespace Eflong.Monitor
{
    /// <summary>
    /// 传感器分类
    /// </summary>
    public enum SensorModalityEnum
    {
        NoType = 0 ,
        Analog = 1 ,
        Digital = 2 ,
        Addup = 3
    }

    public struct SensorTypesStruct
    {
        public Modalities Modality;

        public string Unit;
        public int Type;

        // 开关量状态描述

        public string[ ] Values;

        public SensorTypesStruct( Modalities modality , string unit , int type , string[ ] values )
        {
            Modality = modality;
            Unit = unit;
            Type = type;
            Values = values;
        }

        public SensorTypesStruct( Modalities modality , string unit , int type )
        {
            Modality = modality;
            Unit = unit;
            Type = type;
            Values = new string[ 3 ];
        }
    }

    public class SensorTypes
    {
        public Dictionary<string , SensorTypesStruct> dic_Types = new Dictionary<string , SensorTypesStruct>( );

        public static string[ ] analogTypes = new string[ ]
                                                 {
                                                     "甲烷", "瓦斯", "风速", "温度", "一氧化碳", "风量", "负压", "压力", "流量", "CO2", "高浓甲烷",
                                                     "电压", "电流", "功率",
                                                     "无功", "电量", "氧气", "水位", "煤位", "高度", "位移", "重量", "计时", "计数",
                                                     "模拟量", "累计量"
                                                 };

        public static string[ ] analogUnits = new string[ ]
                                                 {
                                                     "%", "%", "m/s", "℃", "ppm", "m^3/min", "Kpa", "Kpa", "m^3/min", "%", "%CH4", "kV"
                                                     , "A", "kW", "kVAR", "kW.h", "%", "m", "m", "m", "m", "kg", "h", "", "", ""
                                                 };

        public static string[ ] digitalTypes = new string[ ]
                                                  {
                                                      "分站", "断电器", "开停", "开关", "风机", "烟雾", "控制器", "机组", "供电", "皮带", "风门"
                                                      ,
                                                      "馈电", "水泵", "主扇", "局扇", "风筒", "控制量", "界闭", "闭锁"
                                                  };

        public static string[ ] nTypes = new string[ ]
                                               {
                                                   "无", "瓦斯", "风速", "温度", "一氧化碳", "分站", "断电器", "开停", "开关", "风量",
                                                   "负压", "压力", "流量", "风机", "烟雾", "控制器", "机组", "供电", "皮带", "风门",
                                                   "馈电", "水泵", "主扇", "局扇", "风筒", "CO2", "高浓瓦斯", "电压", "电流", "功率",
                                                   "无功", "电量", "氧气", "水位", "煤位", "高度", "位移", "重量", "计时", "计数",
                                                   "模拟量", "累计量", "控制量", "界闭", "闭锁"
                                               };

        private static SensorTypes instance = null;

        private SensorTypes( )
        {
            Init( );
        }

        private void Init( )
        {
            int nType = 1;
            dic_Types.Add( "甲烷" , new SensorTypesStruct( Modalities.Analog , "%" , nType++ ) );
            dic_Types.Add( "瓦斯" , new SensorTypesStruct( Modalities.Analog , "%" , nType ) );
            dic_Types.Add( "风速" , new SensorTypesStruct( Modalities.Analog , "m/s" , nType++ ) );
            dic_Types.Add( "温度" , new SensorTypesStruct( Modalities.Analog , "℃" , nType++ ) );
            dic_Types.Add( "一氧化碳" , new SensorTypesStruct( Modalities.Analog , "ppm" , nType++ ) );
            dic_Types.Add( "分站" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "正常" , "异常" } ) );
            dic_Types.Add( "断电器" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "正常" , "异常" } ) );
            dic_Types.Add( "断电" , new SensorTypesStruct( Modalities.Digital , " " , nType , new string[ ] { "正常" , "断电" } ) );
            dic_Types.Add( "开停" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "开" , "停" } ) );
            dic_Types.Add( "开关" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "开" , "关" } ) );
            dic_Types.Add( "风量" , new SensorTypesStruct( Modalities.Digital , "m^3/min" , nType++ ) );
            dic_Types.Add( "负压" , new SensorTypesStruct( Modalities.Analog , "Kpa" , nType++ ) );
            dic_Types.Add( "压力" , new SensorTypesStruct( Modalities.Analog , "Kpa" , nType++ ) );
            dic_Types.Add( "流量" , new SensorTypesStruct( Modalities.Analog , "m^3/min" , nType++ ) );
            dic_Types.Add( "风机" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "开" , "停" } ) );
            dic_Types.Add( "烟雾" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "无烟" , "有烟" } ) );
            dic_Types.Add( "控制" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "正常" , "异常" } ) );
            dic_Types.Add( "控制器" , new SensorTypesStruct( Modalities.Digital , " " , nType , new string[ ] { "正常" , "异常" } ) );
            dic_Types.Add( "机组" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "开" , "停" } ) );
            dic_Types.Add( "供电" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "开" , "停" } ) );
            dic_Types.Add( "皮带" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "交流" , "直流" } ) );
            dic_Types.Add( "风门" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "关" , "开" } ) );
            dic_Types.Add( "馈电" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "无电" , "有电" } ) );
            dic_Types.Add( "馈电器" , new SensorTypesStruct( Modalities.Digital , " " , nType , new string[ ] { "无电" , "有电" } ) );
            dic_Types.Add( "水泵" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "开" , "停" } ) );
            dic_Types.Add( "主扇" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "开" , "停" } ) );
            dic_Types.Add( "局扇" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "开" , "停" } ) );
            dic_Types.Add( "风筒" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "正常" , "漏风" } ) );
            dic_Types.Add( "CO2" , new SensorTypesStruct( Modalities.Analog , " " , nType++ ) );
            dic_Types.Add( "高浓瓦斯" , new SensorTypesStruct( Modalities.Analog , "%CH4" , nType++ ) );
            dic_Types.Add( "高浓甲烷" , new SensorTypesStruct( Modalities.Analog , "%CH4" , nType ) );
            dic_Types.Add( "电压" , new SensorTypesStruct( Modalities.Analog , "kV" , nType++ ) );
            dic_Types.Add( "电流" , new SensorTypesStruct( Modalities.Analog , "A" , nType++ ) );
            dic_Types.Add( "功率" , new SensorTypesStruct( Modalities.Analog , "kW" , nType++ ) );
            dic_Types.Add( "无功" , new SensorTypesStruct( Modalities.Analog , "kVAR" , nType++ ) );
            dic_Types.Add( "电量" , new SensorTypesStruct( Modalities.Analog , "kW.h" , nType++ ) );
            dic_Types.Add( "氧气" , new SensorTypesStruct( Modalities.Analog , "%" , nType++ ) );
            dic_Types.Add( "水位" , new SensorTypesStruct( Modalities.Analog , "m" , nType++ ) );
            dic_Types.Add( "煤位" , new SensorTypesStruct( Modalities.Analog , "m" , nType++ ) );
            dic_Types.Add( "高度" , new SensorTypesStruct( Modalities.Analog , "m" , nType++ ) );
            dic_Types.Add( "位移" , new SensorTypesStruct( Modalities.Analog , "m" , nType++ ) );
            dic_Types.Add( "重量" , new SensorTypesStruct( Modalities.Analog , "kg" , nType++ ) );
            dic_Types.Add( "计时" , new SensorTypesStruct( Modalities.Analog , "h" , nType++ ) );
            dic_Types.Add( "计数" , new SensorTypesStruct( Modalities.Analog , "n" , nType++ ) );
            dic_Types.Add( "模拟量" , new SensorTypesStruct( Modalities.Analog , " " , nType++ ) );
            dic_Types.Add( "累计量" , new SensorTypesStruct( Modalities.Analog , " " , nType++ ) );
            dic_Types.Add( "控制量" , new SensorTypesStruct( Modalities.Digital , " " , nType++ ) );
            dic_Types.Add( "界闭" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "正常" , "异常" } ) );
            dic_Types.Add( "闭锁" , new SensorTypesStruct( Modalities.Digital , " " , nType++ , new string[ ] { "正常" , "闭锁" } ) );
        }

        public static SensorTypes getInstance( )
        {
            if ( instance == null )
            {
                instance = new SensorTypes( );
            }
            return instance;
        }
    }

    /// <summary>
    /// 传感器信息类
    /// </summary>
    public class SensorInfo
    {
        /// <summary>
        /// 传感器唯一标志
        /// 例如：3-01A01
        /// </summary>
        public string symbol;

        /// <summary>
        /// 矿的ID
        /// </summary>
        public int CoalMineId;

        /// <summary>
        /// 矿名称
        /// </summary>
        public string CoalMineName;

        /// <summary>
        /// 传感器的 ID
        /// </summary>
        public string MonUnitId;

        /// <summary>
        /// 名称及地点信息
        /// </summary>
        public string Name;

        /// <summary>
        /// 传感器分类
        /// 1:模拟量 2：开关量 3：累计量
        /// </summary>
        public Modalities Modality;

        /// <summary>
        /// 传感器类型
        ///     甲烷、一氧化碳、风速
        ///     风机、风门、主扇、局扇
        /// </summary>
        public MonitoringUnitType.Types Type;

        //
        /// <summary>
        /// 传感器类型名
        /// </summary>
        public string sType;

        //
        /// <summary>
        /// 传感器单位
        /// </summary>
        public string sUnit = string.Empty;

        //
        /// <summary>
        /// 报警下限
        /// </summary>
        public float LowerLimit;

        //
        /// <summary>
        /// 报警上限
        /// </summary>
        public float UpperLimit;

        //
        /// <summary>
        /// 断电门限
        /// </summary>
        public float PowerOffLimit;

        //
        /// <summary>
        /// 复电门限
        /// </summary>
        public float PowerOnLimit;

        /// <summary>
        /// 当前值
        /// </summary>
        public float Value;

        /// <summary>
        /// 状态
        /// </summary>
        public States State;

        /// <summary>
        /// 文字描述
        /// </summary>
        public string[ ] ValueDecs = new string[ 3 ];

        /// <summary>
        /// 状态改变时刻
        /// </summary>
        public DateTime StateChangeTime = DateTime.Today;

        /// <summary>
        /// 数据改变时刻
        /// </summary>
        public DateTime DataChangeTime = DateTime.Today;

        /// <summary>
        /// 报警值
        /// </summary>
        public float AlertValue;

        //
        /// <summary>
        /// 断电值
        /// </summary>
        public float BreakValue;

        //
        /// <summary>
        /// 复电值
        /// </summary>
        public float RestValue;

        /// <summary>
        /// 关联的5分钟统计
        /// </summary>
        public Record5Min record5Min;

        // 报警记录集合的 AutoId
        public List<Int32> list_AutoId;

        // 报警历史记录的ID
        public Int32 AutoId;

        /// <summary>
        /// 是否正在报警
        /// </summary>
        public bool IsAlert;

        /// <summary>
        /// 是否正在断电
        /// </summary>
        public bool IsBreak;

        //
        /// <summary>
        /// 是否复电
        /// </summary>
        public bool IsRest;

        /// <summary>
        /// 是否故障
        /// </summary>
        public bool IsFault;

        /// <summary>
        /// 是否已经解除
        /// </summary>
        public bool IsFinish;

        /// <summary>
        /// 是否写入当前报警记录
        /// </summary>
        public bool IsRecord;

        /// <summary>
        /// 是否写入当前实时数据记录
        /// </summary>
        public bool IsRTRecord;

        /// <summary>
        /// 需要写入到当前表的记录
        /// </summary>
        public bool IsNeedRecord;

        /// <summary>
        /// 是否更新
        /// </summary>
        public bool IsUpdate;

        //
        /// <summary>
        /// 需要更新记录吗
        /// </summary>
        public bool IsNeedUpdate;

        /// <summary>
        /// 更新时刻
        /// </summary>
        public DateTime tmUpdate;

        /// <summary>
        /// 开始时刻
        /// </summary>
        public DateTime tmStart;

        /// <summary>
        /// 解除时刻
        /// </summary>
        public DateTime tmStop;

        /// <summary>
        /// 报警原因
        /// </summary>
        public string Causation;

        /// <summary>
        /// 采取措施
        /// </summary>
        public string AdoptMeasure;

        /// <summary>
        /// 采取措施时刻
        /// </summary>
        public DateTime AdoptMeasureTime;

        /// <summary>
        /// 原因分析
        /// </summary>
        public string AnalyseInfo;

        public SensorInfo( )
        {
            record5Min = new Record5Min( );
            tmUpdate = DateTime.Now;
        }

        public void Init( ExcessRecord er )
        {
            symbol = er.CoalMineId.ToString( ) + "-" + er.MonUnitId;
            CoalMineId = er.CoalMineId;
            CoalMineName = er.CoalMineName;
            MonUnitId = er.MonUnitId;
            Name = er.MonUnitName;
            sType = er.MonUnitType.Trim( );
            Modality = er.Modality;
            Type = er.Type;
            if ( Modality == Modalities.Digital )
            {
                ValueDecs = er.ValueDecs;
            }
            else
            {
                sUnit = er.MonUnitUnit;
            }

            if ( Modality < Modalities.Digital || Modality > Modalities.Analog )
            {
                MonitoringUnitType.SensorTypes sensorType = MonitoringUnitType.SensorTypes.模拟量;
                bool b = false;
                Type = MonitoringUnitType.GetMonitoringUnitTypeByName( sType , ref sensorType , ref sUnit , ref ValueDecs , ref b );
                switch ( sensorType )
                {
                    case MonitoringUnitType.SensorTypes.开关量:
                    case MonitoringUnitType.SensorTypes.控制量:
                        Modality = Modalities.Digital;
                        ValueDecs[ 2 ] = ValueDecs[ 1 ];
                        break;
                    default:
                        Modality = Modalities.Analog;
                        break;
                }
            }
            UpdateInfo( er );
        }

        /// <summary>
        /// 更新原因及分析
        /// </summary>
        /// <param name="er"></param>
        public void UpdateInfo( ExcessRecord er )
        {
            if ( er.Causation != null )
            {
                Causation = er.Causation;
            }
            if ( er.AdoptMeasure != null )
            {
                AdoptMeasure = er.AdoptMeasure;
            }
            if ( er.AnalyseInfo != null )
            {
                AnalyseInfo = er.AnalyseInfo;
            }
            if ( er.AdoptMeasureTime.Year > 1 )
            {
                AdoptMeasureTime = er.AdoptMeasureTime;
            }
        }
    }
}